package kingwing.dc.core.view.info;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import kingwing.dc.core.model.EmotionAn;
import kingwing.dc.core.model.Infos;
import kingwing.dc.core.model.KeyWord;
import kingwing.dc.core.model.LexicalAnalysis;
import kingwing.dc.core.model.NewsCat;
import kingwing.dc.core.model.Rule;
import kingwing.dc.core.model.RuleDetail;
import kingwing.dc.core.orm.hibernate.CommonHibernateDao;
import kingwing.dc.core.sevice.SinglePageHtmlProcessor;
import kingwing.dc.core.view.rule.RulePR;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.pipeline.ResultItemsCollectorPipeline;

import com.baidu.aip.nlp.AipNlp;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.view.View;
import com.bstek.dorado.view.widget.Align;
import com.bstek.dorado.view.widget.base.Dialog;
import com.bstek.dorado.view.widget.base.FieldSet;
import com.bstek.dorado.view.widget.base.tab.TabControl;
import com.bstek.dorado.view.widget.data.DataSet;
import com.bstek.dorado.view.widget.form.TemplateField;
import com.bstek.dorado.view.widget.form.TextArea;
import com.bstek.dorado.view.widget.grid.DataColumn;
import com.bstek.dorado.view.widget.grid.DataGrid;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;



@Component
public class InfoShowPR {
	
	@Resource(name=CommonHibernateDao.BEAN_ID)
	private CommonHibernateDao commonHibernateDao;
	
	@Resource(name="rulePR")
	private RulePR rulePR;
	
	/**
	 * 根据规则名称获取规则明细
	 * @param name
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@DataProvider
	public Collection<RuleDetail> getRuleDetails(String ruleName){
		DetachedCriteria detachedCriteriaRule = DetachedCriteria.forClass(Rule.class);
		if (StringUtils.isNotBlank(ruleName)) {
			detachedCriteriaRule.add(Restrictions.eq("ruleName", ruleName));
		}
		List<Rule> rules = (List<Rule>) this.commonHibernateDao.query(detachedCriteriaRule);
		String ruleId = null;
		if (!rules.isEmpty() && rules != null) {
			ruleId = rules.get(0).getId();
		}
		/*********************************************************************/
		DetachedCriteria detachedCriteriaRuleDetail = DetachedCriteria.forClass(RuleDetail.class);
		if (StringUtils.isNotBlank(ruleId)) {
			detachedCriteriaRuleDetail.add(Restrictions.eq("ruleId", ruleId));
		}
		return (Collection<RuleDetail>) this.commonHibernateDao.query(detachedCriteriaRuleDetail);
		
	}
	
	/**
	 * 依据规则名称、关键字分页获取采集信息
	 * @param page
	 */
	@DataProvider
	public void getInfosPage(Page<Infos> page,Map<String , Object> params ){
		String ruleName = null;
		String text = null;
//		boolean checkBox = false;
		if (!params.isEmpty() && params !=null) {
			ruleName = params.get("ruleName").toString();
			text = params.get("text").toString();
//			checkBox = (boolean) params.get("checkBox");
		}
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Infos.class);
//		if (StringUtils.isNotBlank(ruleName)&&!checkBox) {
//		}
		detachedCriteria.add(Restrictions.eq("ruleName", ruleName));
		if (StringUtils.isNotBlank(text)) {
			detachedCriteria.add(Restrictions.or(Restrictions.ilike("field1", "%"+text+"%"),
					Restrictions.ilike("field2", "%"+text+"%")));
//			detachedCriteria.add(Restrictions.like("field1", "%"+text+"%"));
		}
		detachedCriteria.add(Restrictions.eq("createUserId", ContextHolder.getLoginUserName()));
		detachedCriteria.addOrder(Order.desc("field3"));
		
		this.commonHibernateDao.pagingQuery(page, detachedCriteria);
	}
	
		
	/**
	 * 动态展示页面
	 * @param view
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public void onViewInit(View view) throws Exception{
		
		DataGrid dataGridInfos = (DataGrid) view.getViewElement("dataGridInfos");
		DataSet dataSetRuleDetail = (DataSet) view.getViewElement("dataSetRuleDetail");
		
		String caption =java.net.URLDecoder.decode(ContextHolder.getRequest().getParameter("caption"),"UTF-8");
		
		dataSetRuleDetail.setParameter(caption);
		
		//获取规则细则数据，动态生成DataGrid列表项
		List<RuleDetail> ruleDetails = (List<RuleDetail>) dataSetRuleDetail.getData();
		
		if (ruleDetails != null) {
			
			/*
			 * 判断管理员是否显示信息所属列
			 * 
			if (ContextHolder.getLoginUser().isAdministrator()) {
				DataColumn dataColumn = new DataColumn();
				dataColumn.setAlign(Align.center);
				dataColumn.setName("createUserId");
				dataColumn.setProperty("createUserId");
				dataGridInfos.addColumn(dataColumn);
			}
			*/
			
			for (int i = 0; i < ruleDetails.size(); i++) {
				
				RuleDetail ruleDetail = ruleDetails.get(i);
				if (ruleDetail==null) {
					continue;
				}
				
				int fieldType = ruleDetail.getFieldType();
				
				//配置dataGridInfos
				if (ruleDetails.get(i).isRuleDetailColumn()) {
					DataColumn dataColumn = new DataColumn();
					dataColumn.setAlign(Align.center);
					dataColumn.setCaption(ruleDetails.get(i).getRuleDetailName());
					dataColumn.setName("field"+(ruleDetails.get(i).getFieldType()+1));
					dataColumn.setProperty("field"+(ruleDetails.get(i).getFieldType()+1));
					dataGridInfos.addColumn(dataColumn);
				}
			}
		}else {
			DataColumn dataColumn = new DataColumn();
			dataColumn.setAlign(Align.center);
			dataColumn.setCaption("提示:请检查该站点的规则是否设置了规则明细！");
			dataColumn.setReadOnly(true);
			dataGridInfos.addColumn(dataColumn);
		}
		
	}
	
	/**
	 * 情感分析代码
	 * @param text
	 */
	@Transactional
	@Expose
	public void getEmotionData(Map<String, Object> params){
		
		String text ="";
		String id ="";
		String title ="";
		String ruleName ="";
		if (params!=null && !params.isEmpty()) {
			text = params.get("text").toString();
			id = params.get("id").toString();
			title = params.get("title").toString();
			ruleName = params.get("ruleName").toString();
		}
		
		if (isCountEmotionAn(id, title)) {
			return ;
		}
		
		if (StringUtils.isNotBlank(text)) {
				String body = new JSONArray(new String[]{text}).toString();
				try {
					HttpResponse<JsonNode> jsonResponse = Unirest.post("http://api.bosonnlp.com/sentiment/analysis")
							.header("Accept", "application/json")
							.header("X-Token", "wL-ZYNNF.17656.cwmFNNsIADqg")
							.body(body)
							.asJson();
					
					JsonNode jn = jsonResponse.getBody();
					
					JSONArray ja = null;
					if (jn!=null) {
						ja = jn.getArray();
					}
					
					if (ja!=null) {
						EmotionAn ea = new EmotionAn();
						JSONArray jaDetail = ja.getJSONArray(0);
						ea.setFront(jaDetail.get(0).toString());
						ea.setDownside(jaDetail.get(1).toString());
						ea.setInfosId(id);
						ea.setInfosTitle(title);
						ea.setRuleName(ruleName);
						
						this.commonHibernateDao.save(ea);
					}
					
					// Unirest starts a background event loop and your Java
					// application won't be able to exit until you manually
					// shutdown all the threads
					//Unirest.shutdown();
				} catch (Exception e) {
					System.out.println("情感分析分析失败！");
				}
		}

	}

	/**
	 * 判断情感分析表中是否已经存在已有的情感分析！
	 * @param id
	 * @param title
	 * @return
	 */
	private boolean isCountEmotionAn(String id, String title) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(EmotionAn.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("infosId", id), 
				Restrictions.eq("infosTitle", title)) );
		detachedCriteria.add(Restrictions.eq("createUserId", ContextHolder.getLoginUser().getUsername()));
		int count = this.commonHibernateDao.queryCount(detachedCriteria);
		
		if (count>0) {
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 关键词提取代码
	 * @param text
	 */
	@Transactional
	@Expose
	public void getKeyWordData(Map<String, Object> params){
		
		String text ="";
		String id ="";
		String title ="";
		String ruleName ="";
		if (params!=null && !params.isEmpty()) {
			text = params.get("text").toString();
			id = params.get("id").toString();
			title = params.get("title").toString();
			ruleName = params.get("ruleName").toString();
		}
		
		if (isCountKeyWord(id, title)) {
			return ;
		}
		
		if (StringUtils.isNotBlank(text)) {
			String body = new JSONArray(new String[]{text}).toString();
			try {
				HttpResponse<JsonNode> jsonResponse = Unirest.post("http://api.bosonnlp.com/keywords/analysis")
						.header("Accept", "application/json")
						.header("X-Token", "wL-ZYNNF.17656.cwmFNNsIADqg")
						.body(body)
						.asJson();
				
				
				JsonNode jn = jsonResponse.getBody();
				
				JSONArray ja = null;
				if (jn!=null) {
					ja = jn.getArray().getJSONArray(0);
				}
				
				if (ja!=null) {
					for (int i = 0; i < ja.length(); i++) {
						KeyWord kw = new KeyWord();
						JSONArray jaDetail = ja.getJSONArray(i);
						kw.setWeight(jaDetail.getDouble(0));
						kw.setName(jaDetail.getString(1));
						kw.setInfosId(id);
						kw.setInfosTitle(title);
						kw.setRuleName(ruleName);
						
						this.commonHibernateDao.save(kw);
					}
				}
				
				// Unirest starts a background event loop and your Java
				// application won't be able to exit until you manually
				// shutdown all the threads
				//Unirest.shutdown();
			} catch (Exception e) {
				System.out.println("关键词分析失败！");
			}
		}
	}
	
	/**
	 * 判关键词表中是否已经存在已有的关键词！
	 * @param id
	 * @param title
	 * @return
	 */
	private boolean isCountKeyWord(String id, String title) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(KeyWord.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("infosId", id), 
				Restrictions.eq("infosTitle", title)) );
		detachedCriteria.add(Restrictions.eq("createUserId", ContextHolder.getLoginUser().getUsername()));
		int count = this.commonHibernateDao.queryCount(detachedCriteria);
		
		if (count>0) {
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 分页获取关键词信息
	 * @param page
	 * @param id
	 * @param title
	 */
	@DataProvider
	public void getKeyWordPages(Page<KeyWord> page,String id, String title) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(KeyWord.class);
		
		if (StringUtils.isNotBlank(id)||StringUtils.isNotBlank(title)) {
			detachedCriteria.add(Restrictions.or(Restrictions.eq("infosId", id), 
					Restrictions.eq("infosTitle", title)) );
		}
		
		detachedCriteria.add(Restrictions.eq("createUserId", ContextHolder.getLoginUser().getUsername()));
		
		this.commonHibernateDao.pagingQuery(page, detachedCriteria);
		
	}
	
	/**
	 * 词法分析代码
	 * @param params
	 */
	@Transactional
	@Expose
	public void getLexicalAnalysisData(Map<String , Object> params){
		
		//设置APPID/AK/SK
	    final String APP_ID = "10152909";
	    final String API_KEY = "HTCtcyaAfxQLkUsxnxjqDVX8";
	    final String SECRET_KEY = "SK6jUzRn67dBGyZAKRxr8jLmxsrwc0To";
	    
		String text ="";
		String id ="";
		String title ="";
		String ruleName ="";
		if (params!=null && !params.isEmpty()) {
			text = params.get("text").toString();
			id = params.get("id").toString();
			title = params.get("title").toString();
			ruleName = params.get("ruleName").toString();
		}
		
		if (isCountLexicalAnalysis(id, title)) {
			return ;
		}
		
		if (StringUtils.isNotBlank(text)) {
			
			// 初始化一个AipNlp
			AipNlp client = new AipNlp(APP_ID, API_KEY, SECRET_KEY);
			
			// 可选：设置网络连接参数
			client.setConnectionTimeoutInMillis(2000);
			client.setSocketTimeoutInMillis(60000);
			
			JSONObject response = client.lexer(text);
			
			JSONArray jsonArray = response.getJSONArray("items");
			
			for (int i = 0; i < jsonArray.length(); i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				LexicalAnalysis lexicalAnalysis = new LexicalAnalysis();
				lexicalAnalysis.setInfosId(id);
				lexicalAnalysis.setInfosTitle(title);
				lexicalAnalysis.setRuleName(ruleName);
				lexicalAnalysis.setItem(jsonObject.getString("item"));
				lexicalAnalysis.setNe(jsonObject.getString("ne"));
				lexicalAnalysis.setPos(jsonObject.getString("pos"));
				lexicalAnalysis.setBasicWords(jsonObject.getJSONArray("basic_words").toString());
				lexicalAnalysis.setByteLength(jsonObject.getInt("byte_length"));
				lexicalAnalysis.setByteOffset(jsonObject.getInt("byte_offset"));
				
				this.commonHibernateDao.save(lexicalAnalysis);
			}
		}
		
	}
	
	/**
	 * 判词法分析表中是否已经存在已有的分析！
	 * @param id
	 * @param title
	 * @return
	 */
	private boolean isCountLexicalAnalysis(String id, String title) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(LexicalAnalysis.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("infosId", id), 
				Restrictions.eq("infosTitle", title)) );
		detachedCriteria.add(Restrictions.eq("createUserId", ContextHolder.getLoginUser().getUsername()));
		int count = this.commonHibernateDao.queryCount(detachedCriteria);
		
		if (count>0) {
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 分页获取词性标识信息
	 * @param page
	 * @param id
	 * @param title
	 */
	@DataProvider
	public void getKeyLexicalAnalysisPages(Page<LexicalAnalysis> page,String id, String title,String pos,String ne) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(LexicalAnalysis.class);
		
		if (StringUtils.isNotBlank(id)||StringUtils.isNotBlank(title)) {
			detachedCriteria.add(Restrictions.or(Restrictions.eq("infosId", id), 
					Restrictions.eq("infosTitle", title)) );
		}
		if (StringUtils.isNotBlank(pos)) {
			detachedCriteria.add(Restrictions.eq("pos", pos));
		}
		
		if (StringUtils.isNotBlank(ne)) {
			detachedCriteria.add(Restrictions.eq("ne", ne));
		}
		detachedCriteria.add(Restrictions.eq("createUserId", ContextHolder.getLoginUser().getUsername()));
		this.commonHibernateDao.pagingQuery(page, detachedCriteria);
		
	}
	
	/**
	 * 新闻分类逻辑代码
	 */
	@Transactional
	@Expose
	public void getNewsCatData(Map<String , Object> params){
		
		final String SENTIMENT_URL =
		        "http://api.bosonnlp.com/classify/analysis";
		String text ="";
		String id ="";
		String title ="";
		String ruleName ="";
		if (params!=null && !params.isEmpty()) {
			text = params.get("text").toString();
			id = params.get("id").toString();
			title = params.get("title").toString();
			ruleName = params.get("ruleName").toString();
		}
		
		if (isCountNewsCat(id, title)) {
			return ;
		}
		
		Map<Integer , String> map = new HashMap<Integer, String>();
		map.put(0, "体育");
		map.put(1, "教育");
		map.put(2, "财经");
		map.put(3, "社会");
		map.put(4, "娱乐");
		map.put(5, "军事");
		map.put(6, "国内");
		map.put(7, "科技");
		map.put(8, "互联网");
		map.put(9, "房产");
		map.put(10, "国际");
		map.put(11, "女人");
		map.put(12, "汽车");
		map.put(13, "游戏");
		
		if (StringUtils.isNotBlank(text)) {
			
			String body = new JSONArray(new String[]{text}).toString();
			
			
			HttpResponse<JsonNode> json = null;
			try {
				json = Unirest.post(SENTIMENT_URL)
						.header("Content-Type","application/json")
						.header("Accept", "application/json")
						.header("X-Token", "wL-ZYNNF.17656.cwmFNNsIADqg")
						.body(body)
						.asJson();
			} catch (UnirestException e) {
				System.out.println("分析失败！");
			}
			
			NewsCat newsCat = new NewsCat();
			newsCat.setInfosId(id);
			newsCat.setInfosTitle(title);
			newsCat.setRuleName(ruleName);
			newsCat.setNewName(map.get( json.getBody().getArray().getInt(0)));
			newsCat.setType(json.getBody().getArray().getInt(0));
			this.commonHibernateDao.save(newsCat);
		}
		
		
	}
	
	/**
	 * 判新闻分类表中是否已经存在已有的分析！
	 * @param id
	 * @param title
	 * @return
	 */
	private boolean isCountNewsCat(String id, String title) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(NewsCat.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("infosId", id), 
				Restrictions.eq("infosTitle", title)) );
		detachedCriteria.add(Restrictions.eq("createUserId", ContextHolder.getLoginUser().getUsername()));
		int count = this.commonHibernateDao.queryCount(detachedCriteria);
		
		if (count>0) {
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 提供新闻分类角标
	 * @param parms
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Expose
	public int getNewsCatType(String id,String title){
		
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(NewsCat.class);
		
		if (StringUtils.isNotBlank(title)||StringUtils.isNotBlank(id)) {
			detachedCriteria.add(Restrictions.or(Restrictions.eq("infosId", id), 
					Restrictions.eq("infosTitle", title)) );
		}
		detachedCriteria.add(Restrictions.eq("createUserId", ContextHolder.getLoginUser().getUsername()));
		List<NewsCat> newsCatList = (List<NewsCat>) this.commonHibernateDao.query(detachedCriteria);
		
		NewsCat newsCat = null;
		if (newsCatList.size()>0 && newsCatList!=null) {
			newsCat = newsCatList.get(0);
		}
		
		int type = 0;
		if (newsCat!=null) {
			type = newsCat.getType();
		}
		
		return type;
		
	}
	
	/**
	 * 依据规则名称获取规则
	 * @param ruleName
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@DataProvider
	public Rule getRule(String ruleName){
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Rule.class);
		
		if (StringUtils.isNotBlank(ruleName)) {
			detachedCriteria.add(Restrictions.eq("ruleName", ruleName));
		}
		detachedCriteria.add(Restrictions.eq("createUserId", ContextHolder.getLoginUser().getUsername()));
		List<Rule> rules = (List<Rule>) this.commonHibernateDao.query(detachedCriteria);
		
		if (rules.size()>0&&rules!=null) {
			return rules.get(0);
		}else {
			return null;
		}
	}
	
	/**
	 * 根据站点名称清空站点信息
	 * @param ruleName
	 */
	@Transactional
	@Expose
	public void deleteAllInfos(final String ruleName ,final String userName){
		
		if (StringUtils.isNotBlank(ruleName)) {
			this.commonHibernateDao.doInHibernateSession(new ISessionCallback<Object>() {

				@Override
				public Object doInSession(Session session) {
//					String userName = ContextHolder.getLoginUserName();
					//删除信息表
					session.createQuery("delete Infos where ruleName=:ruleName and createUserId=:userName")
					.setString("ruleName", ruleName)
					.setString("userName", userName)
					.executeUpdate();
					//删除情感分析
					session.createQuery("delete EmotionAn where ruleName=:ruleName and createUserId=:userName")
					.setString("ruleName", ruleName)
					.setString("userName", userName)
					.executeUpdate();
					//删除关键字
					session.createQuery("delete KeyWord where ruleName=:ruleName and createUserId=:userName")
					.setString("ruleName", ruleName)
					.setString("userName", userName)
					.executeUpdate();
					//删除词法分析
					session.createQuery("delete LexicalAnalysis where ruleName=:ruleName and createUserId=:userName")
					.setString("ruleName", ruleName)
					.setString("userName", userName)
					.executeUpdate();
					//删除新闻分类
					session.createQuery("delete NewsCat where ruleName=:ruleName and createUserId=:userName")
					.setString("ruleName", ruleName)
					.setString("userName", userName)
					.executeUpdate();
					
					return null;
				}
			});
		}
	}
	
	/**
	 * 内容采集
	 * @param Url
	 * @param rule
	 * @param infos
	 * @return
	 */
	@Transactional
	@Expose
	public String contentCollection(String Url,Rule rule,Infos infos){
		
		if (StringUtils.isBlank(Url) || rule == null) {
			return "Url为NULL";
		}
		
		Site site = Site.me().setDomain(rule.getDomains()).setSleepTime(3000).setRetryTimes(3).setCharset("UTF-8");
		
		List<RuleDetail> ruleDetails = rulePR.getRuleDetails(rule.getId());
		
		ResultItemsCollectorPipeline resultItemsCollectorPipeline = new ResultItemsCollectorPipeline();
		
		
		Spider s = Spider.create(new SinglePageHtmlProcessor(site, rule, ruleDetails));
		s.addUrl(Url);
		s.thread(10);
		s.addPipeline(resultItemsCollectorPipeline);
		s.run();
		
		String result = null; 
		//获取采集结果，进行数据持久化
		List<ResultItems> list = resultItemsCollectorPipeline.getCollected();
		for (ResultItems resultItems : list) {
			String mainText = resultItems.get("mainText");
			result = mainText;
			infos.setField2(mainText);
			this.commonHibernateDao.update(infos);
		}
		
		return result;
		
	}
	
	
	
}
